home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / processes / mp threaded sort / dialogwindow.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  6.8 KB  |  238 lines

  1. /*
  2.     File:        DialogWindow.cp
  3.  
  4.     Contains:    Implementation of a base class for Modeless Dialogs
  5.  
  6.     Written by: Dave Falkenburg    
  7.  
  8.     Copyright:    Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/27/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 11/16/94    DRF                Added explicit #include <Traps.h> for latest universal headers.
  21.                  11/12/94    DRF                Fix a bug in EventFilter method which returned false even if a
  22.                                             dialog item was hit.
  23.                  11/8/94        DRF                We have better menu handling methods, so use them instead of the
  24.                                             old “DoEditMenu” method.
  25.                  10/17/94    DRF                 ItemHit is now a pure-virtual method. Fixed bugs in DoEditMenu.
  26.                                              Call StdFilterProc inside EventFilter to handle ok, cancel,
  27.                                             and I-beam cursor tracking.
  28.                  9/27/94    DRF                 AppLib.h is now Sprocket.h
  29.                   9/9/94    DRF                Reordered headers and removed redundant #includes. Also fixed
  30.                                             constants in DoEditMenu.
  31.  
  32. */
  33.  
  34. #include "Sprocket.h"
  35. #include "DialogWindow.h"
  36. #include "StandardMenus.h"
  37. #include <Traps.h>
  38.  
  39. TDialogWindow::TDialogWindow(DialogTemplateID dialogTemplateID)
  40.     {
  41.     fTemplateID = dialogTemplateID;
  42.     this->CreateWindow(kNormalWindow);
  43.     }
  44.  
  45.  
  46. WindowPtr
  47. TDialogWindow::MakeNewWindow(WindowPtr behindWindow)
  48.     {
  49.     return GetNewDialog(fTemplateID,nil,behindWindow);
  50.     }
  51.  
  52.  
  53. ////////////////////////////////////////////////////////////////////////////////////
  54. //
  55. //    EventFilter strategy for Dialog Window
  56. //
  57. //    Because of the need to patch and unpatch FrontWindow when calling IsDialogEvent
  58. //    and DialogSelect, only do these things when a Modless Dialog is the frontmost
  59. //    window. (e.g., it’s event filter is active)
  60. //
  61. //    NOTE: We always pass events through, except when an item has been hit.
  62. //
  63. //    You may be thinking that it is easier to just rewrite the Dialog Manager in
  64. //    this program. You’re probably right.
  65.  
  66. pascal    WindowPtr    FrontWindowPatchForDialogs();
  67.  
  68.  
  69. pascal    WindowPtr
  70. FrontWindowPatchForDialogs()
  71.     {
  72.     return MyFrontNonFloatingWindow();
  73.     }
  74.  
  75. #define    uppFrontWindowPatchProcInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
  76.  
  77. UniversalProcPtr FrontWindowPatchUPP
  78. = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) &FrontWindowPatchForDialogs,uppFrontWindowPatchProcInfo,GetCurrentISA());
  79.  
  80.  
  81. Boolean
  82. TDialogWindow::EventFilter(EventRecord *theEvent)
  83.     {
  84.     GrafPtr                oldPort;
  85.     UniversalProcPtr    oldFrontWindow = GetToolboxTrapAddress(_FrontWindow);
  86.     DialogPtr            aDialog;
  87.     Boolean                eventHasBeenGobbled = false;
  88.     short                aDialogItem;
  89.     short                oldWindowKind;
  90.     
  91.     //    Don’t snarf keypresses meant for menus
  92.     if ((theEvent->what == keyDown) && (theEvent->modifiers & cmdKey))
  93.         return false;
  94.  
  95.     GetPort(&oldPort);
  96.     SetPort(fWindow);
  97.     
  98.     //    Patch in our version of FrontWindow so that IsDialogEvent will do the right
  99.     //    thing. DialogManager should check both frontmost floating and frontmost
  100.     //    non-floating windows, however we don’t support floating dialogs.
  101.     SetToolboxTrapAddress(FrontWindowPatchUPP,_FrontWindow);
  102.  
  103.     //    Jam the windowKind of our dialog window back to dialogKind so that the
  104.     //    Dialog Manager can recognize our window as a dialog window.
  105.     oldWindowKind = ((WindowPeek) fWindow)->windowKind;
  106.     ((WindowPeek) fWindow)->windowKind = dialogKind;
  107.     
  108.     
  109.     if (IsDialogEvent(theEvent))
  110.         {
  111.         //    It’s definitely a dialog event, so let the DialogMgr figure things out.
  112.         //
  113.         //    We first let StdFilterProc have a crack at it so that the default
  114.         //    and cancel buttons are properly processed (as well as automagic text
  115.         //    cursor tracking).
  116.         
  117.         //    If StdFilterProc didn’t find anything to do, go ahead and call
  118.         //    DialogSelect to figure out if the user did anything important.
  119.  
  120.         //    Isn’t this alot easier than what Inside Mac says to do?
  121.  
  122.         eventHasBeenGobbled = StdFilterProc(fWindow,theEvent,&aDialogItem);
  123.         if (eventHasBeenGobbled == false)
  124.             eventHasBeenGobbled = DialogSelect(theEvent,&aDialog,&aDialogItem);
  125.         }
  126.  
  127.     //    Restore the windowKind
  128.     ((WindowPeek) fWindow)->windowKind = oldWindowKind;
  129.  
  130.     //    Put FrontWindow back the way it really belongs
  131.     SetToolboxTrapAddress((UniversalProcPtr) oldFrontWindow,_FrontWindow);
  132.  
  133.     if (eventHasBeenGobbled)
  134.         {
  135.         this->ItemHit(aDialogItem);    //    Call user’s method to deal with a hit
  136.         eventHasBeenGobbled = true;
  137.         }
  138.         
  139.     SetPort(oldPort);
  140.     
  141.     return eventHasBeenGobbled;
  142.     }
  143.  
  144.  
  145. void
  146. TDialogWindow::Activate(Boolean activating)
  147.     {
  148.     EventRecord            fakeEvent;
  149.  
  150.     /*    (De)activates are NOT automagically handled because our floating
  151.      *    windows prevent real activate events from ever being generated
  152.      *    for any non-floaters windows.
  153.      *
  154.      *    Our strategy is to fool the dialog manager into thinking that
  155.      *    things are still fine by passing it a fake (de)activate event.
  156.      *
  157.      *    Luckily, we don’t have to patch FrontWindow to make DialogSelect
  158.      *    work for activate and update events.
  159.      */
  160.         
  161.     OSEventAvail(0,&fakeEvent);        //    Get an intialized, but otherwise empty event record
  162.     
  163.     fakeEvent.what = activateEvt;
  164.     fakeEvent.message = (unsigned long) fWindow;
  165.     if (activating)
  166.         fakeEvent.modifiers |= activeFlag;
  167.     else
  168.         fakeEvent.modifiers &= ~activeFlag;
  169.  
  170.     //    Pass event on to DialogSelect
  171.     
  172.     DialogPtr    aDialog;
  173.     short        aDialogItem;
  174.     
  175.     (void) DialogSelect(&fakeEvent,&aDialog,&aDialogItem);
  176.     }
  177.     
  178.  
  179. void
  180. TDialogWindow::Draw(void)
  181.     {
  182.     //    Automagically handled by Dialog Manager when we are
  183.     //    the frontmost window, but not at other times because
  184.     //    we only set the windowKind to dialogKind inside our
  185.     //    EventFilter (which is only active when we are frontmost).
  186.     
  187.     UpdateDialog((DialogPtr) fWindow, fWindow->visRgn);
  188.     }
  189.     
  190.     
  191. void
  192. TDialogWindow::Click(EventRecord * /* anEvent */)
  193.     {
  194.     /*    The only time this method is called is to handle a click
  195.      *    when the dialog window isn’t frontmost. All other times,
  196.      *    DialogSelect will do everything for us.
  197.      *
  198.      *    If our dialog contains useritems with the ability to
  199.      *    be the source of a drag we’d need to start drag tracking
  200.      *    in here.
  201.      */
  202.      
  203.     this->Select();
  204.     }
  205.  
  206.     
  207. void
  208. TDialogWindow::DoMenuSelection(short menu, short item)
  209.     {
  210.     if (menu == mEdit)
  211.         {
  212.         switch (item)
  213.             {
  214.             case    iUndo:
  215.                 break;
  216.                 
  217.             case    iCut:
  218.                 DialogCut(fWindow);
  219.                 return;
  220.                 
  221.             case    iCopy:
  222.                 DialogCopy(fWindow); 
  223.                 return;
  224.                 
  225.             case    iPaste:
  226.                 DialogPaste(fWindow); 
  227.                 return;
  228.                 
  229.             case    iClear:
  230.                 DialogDelete(fWindow); 
  231.                 return;
  232.             }
  233.         }
  234.     
  235.     //    Call through to inherited method
  236.     TWindow::DoMenuSelection(menu,item);
  237.     }
  238.